#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
using namespace std;
#include <semaphore.h>

int ticket = 1000;

class SEM
{
  private: 
    sem_t _sem;
  public:
    SEM(int num = 1)
    {
      sem_init(&_sem , 0 , num);
    }

    ~SEM()
    {
      sem_destroy(&_sem);
    }

    void P()
    {
      sem_wait(&_sem);
    }

    void V()
    {
      sem_post(&_sem);
    }
};

SEM s(1);

void* TicketGrabbing(void* arg)
{
  string name = (char *)arg;
  while(1)
  {
    s.P();
    if (ticket > 0)
    { 
      usleep(1000);  
      cout << name << ": get a ticket ticket left : " << --ticket << endl;
      s.V();
    }
    else 
    {
      s.V();
      break;
    }
  }

  cout << "there is no ticket" << endl;
  pthread_exit((void *)0);
}



int main()
{
  pthread_t tid1 , tid2 , tid3 , tid4;
  pthread_create(&tid1, nullptr, TicketGrabbing, (void*)"thread 1");
	pthread_create(&tid2, nullptr, TicketGrabbing, (void*)"thread 2");
	pthread_create(&tid3, nullptr, TicketGrabbing, (void*)"thread 3");
	pthread_create(&tid4, nullptr, TicketGrabbing, (void*)"thread 4");

  pthread_join(tid1, nullptr);
  pthread_join(tid2, nullptr);
  pthread_join(tid3, nullptr);
  pthread_join(tid4, nullptr);
  return 0;
}
